package cn.chengpengper.shortlink.service.impl;

import cn.chengpengper.shortlink.constant.ShortLinkMsg;
import cn.chengpengper.shortlink.controller.request.AccountLoginRequest;
import cn.chengpengper.shortlink.controller.request.AccountRegisterRequest;
import cn.chengpengper.shortlink.convert.AccountConverter;
import cn.chengpengper.shortlink.enums.BizCodeEnum;
import cn.chengpengper.shortlink.enums.SendCodeEnum;
import cn.chengpengper.shortlink.model.AccountDO;
import cn.chengpengper.shortlink.model.LoginUser;
import cn.chengpengper.shortlink.repository.AccountRepository;
import cn.chengpengper.shortlink.service.AccountService;
import cn.chengpengper.shortlink.service.CaptchaService;
import cn.chengpengper.shortlink.util.JsonData;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.Md5Crypt;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;
import java.util.Objects;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author huchengpeng
 * @since 2023-08-20
 */
@Slf4j
@Service
public class AccountServiceImpl implements AccountService {

    @Autowired
    private CaptchaService captchaService;

    @Autowired
    private AccountRepository accountRepository;

    @Override
    public JsonData register(AccountRegisterRequest registerRequest) {
        if (StringUtils.isBlank(registerRequest.getCode())) {
            return JsonData.buildResult(BizCodeEnum.OPS_INVALID_PARAM, ShortLinkMsg.EMPYT_CAPTCHA);
        }

        if (StringUtils.isBlank(registerRequest.getPhone())) {
            return JsonData.buildResult(BizCodeEnum.OPS_INVALID_PARAM, ShortLinkMsg.EMPYT_PHONE);
        }

        // 1、判断短信验证码
        if (!captchaService.captchaVerify(SendCodeEnum.USER_REGISTER, registerRequest.getPhone(), registerRequest.getCode())) {
            return JsonData.buildResult(BizCodeEnum.CODE_ERROR);
        }

        // 2、判断是否已经注册过
        AccountDO existAccount = accountRepository.findByPhone(registerRequest.getPhone());
        if (Objects.nonNull(existAccount)) {
            log.error("AccountServiceImpl | register | Account already exist:{}. 注册失败", existAccount);
            return JsonData.buildResult(BizCodeEnum.ACCOUNT_REPEAT);
        }

        // 3、构建新的账号实体
        AccountDO accountDO = AccountConverter.registerRequest2DO(registerRequest);

        int rows = accountRepository.insert(accountDO);
        if (rows == 0) {
            log.error("AccountServiceImpl | register | Account:{}. rows is {}, 注册失败", registerRequest, rows);
            return JsonData.buildResult(BizCodeEnum.ACCOUNT_REGISTER_ERROR);
        }
        log.info("AccountServiceImpl | register | Account:{}. rows is {}, 注册成功", registerRequest, rows);
        // TODO 用户注册成功，发放福利
        return JsonData.buildSuccess();
    }

    @Override
    public JsonData login(AccountLoginRequest loginRequest) {
        if (StringUtils.isBlank(loginRequest.getPhone())) {
            return JsonData.buildResult(BizCodeEnum.OPS_INVALID_PARAM, ShortLinkMsg.EMPYT_PHONE);
        }

        if (StringUtils.isBlank(loginRequest.getPwd())) {
            return JsonData.buildResult(BizCodeEnum.OPS_INVALID_PARAM, ShortLinkMsg.EMPYT_PWD);
        }

        AccountDO accountDO = accountRepository.findByPhone(loginRequest.getPhone());

        if (Objects.isNull(accountDO)) {
            // 账号不存在
            return JsonData.buildResult(BizCodeEnum.ACCOUNT_UNREGISTER);
        }

        String secret = accountDO.getSecret();
        String cryptPwd = Md5Crypt.md5Crypt(loginRequest.getPwd().getBytes(StandardCharsets.UTF_8), secret);

        if (!StringUtils.equalsIgnoreCase(cryptPwd, accountDO.getPwd())) {
            return JsonData.buildResult(BizCodeEnum.ACCOUNT_PWD_ERROR);
        }
        // TODO 生成Token
        LoginUser loginUser = LoginUser.builder()
                .accountNo(accountDO.getAccountNo())
                .headImg(accountDO.getHeadImg())
                .auth(accountDO.getAuth())
                .username(accountDO.getUsername())
                .phone(accountDO.getPhone())
                .mail(accountDO.getMail())
                .build();

        return JsonData.buildSuccess(loginUser);
    }
}
